/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.qb9.flashlib.locale
{
	import com.qb9.flashlib.interfaces.IDisposable;
	import com.qb9.flashlib.utils.StringUtil;
	
	import flash.display.Stage;
	import flash.events.Event;
	import flash.text.TextField;

	public class Locale implements IDisposable
	{
		private static const DEFAULT_SEPARATOR:String = '#';
		private static const EMPTY_STRING:String = '';
		private static const CARRIAGE_RETURN:String = '\r';
		
		private var stage:Stage;
		private var data:Object;
		private var caseSensitiveKeys:Boolean;
		
		private var _separator:String = DEFAULT_SEPARATOR;
		
		public function Locale(stage:Stage, data:Object, caseSensitiveKeys:Boolean=true)
		{
			this.stage = stage;
			this.data = data;
			this.caseSensitiveKeys = caseSensitiveKeys;
			
			init();
		}
		
		private function init():void
		{
			if (caseSensitiveKeys)
				return;
				
			var lower:Object = {};
			for (var key:String in data)
				lower[key.toLowerCase()] = data[key];
			data = lower;
		}
		
		public function start():void
		{
			stage.addEventListener(Event.ADDED_TO_STAGE, apply, true);
		}
		
		public function stop():void
		{
			stage.removeEventListener(Event.ADDED_TO_STAGE, apply, true);
		}
		
		public function get separator():String
		{
			return _separator;
		}	
		
		public function set separator(v:String):void
		{
			_separator = v;
		}
		
		private function apply(e:Event):void
		{
			var field:TextField = e.target as TextField;
			if (field)
				refresh(field);
		}
		
		// To be used for elements already in the display list
		public function setText(field:TextField, id:String, ...parameters:Array):void
		{
			if (!caseSensitiveKeys)
				id = id.toLowerCase();
			
			if (!data[id])
				return;
				
			var str:String = String(data[id]);
			if (parameters.length)
				str = StringUtil.format(str, parameters);
			field.text = str;
		}
		
		// To be used for elements already in the display with a formatted text
		// The text can contain parameters, also delimited by the same separator
		public function refresh(field:TextField):void
		{
			var parts:Array = getParts(field);
			if (parts.length < 3 || parts[0] !== EMPTY_STRING || parts.pop() !== EMPTY_STRING)
				return;
			
			parts[0] = field;
			setText.apply(null, parts);
		}
		
		private function getParts(field:TextField):Array
		{	
			var text:String = field.text;
			// Flash adds a '\r' char to the end of multiline TextFields
			if (field.multiline && text.slice(-1) === CARRIAGE_RETURN)
				text = text.slice(0, -1);
			return text.split(separator);
		}
		
		public function dispose():void
		{
			stop();			
			stage = null;
			data = null;
		}
		
	}
}